﻿using NUnit.Framework;
using StreetPacMan.Server.Facade;

namespace StreetPacMan.Server.Tests.Integ
{
    [TestFixture]
    public class GameStates : BaseCleaner
    {
        //[Test]
        //public void GetGameState_ObserverJoiningAfterPacMan_MessageShouldStillBeAboutPacMan()
        //{
        //    var instance = ServerFacadeFactory.GetServerFacade();

        //    instance.CreateGameX("GameName");
        //    instance.JoinGameX("GameName", "PacManName", PlayerRole.PacMan);
        //    instance.JoinGameX("GameName", "Observer", PlayerRole.Observer);

        //    var gameState = instance.GetGameStateAsObvserverX("GameName");
        //    Assert.AreEqual(GameState.WaitingForMorePlayersToJoin, gameState.State);
        //    Assert.AreEqual("PacManName joined as PacMan", gameState.LastGameMessage);
        //}

        [Test]
        public void GetGameState_AfterOnPacManJoiningGameAndPollingWhenDisabled_GameStateShouldBeWaitingForPlayersToJoin()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var pacManEntity = instance.JoinGameX("GameName", "PacMan1", PlayerRole.PacMan);
            instance.UpdateMyWhereabouts(new ServerPollParameters(pacManEntity.PlayerId, 5, 5, false));

            Assert.AreEqual(GameState.WaitingForMorePlayersToJoin, instance.GetGameStateAsObvserverX("GameName").State);
        }

        [Test]
        public void GetGameState_AfterPacManEnablingHimself_GameStateShouldBeGameStarted()
        {
            var instance = ServerFacadeFactory.GetServerFacade();
         
            instance.CreateGameX("GameName");
            var pacManEntity = instance.JoinGameX("GameName", "PacMan1", PlayerRole.PacMan);
            instance.UpdateMyWhereabouts(new ServerPollParameters(pacManEntity.PlayerId, 5, 5, true));

            Assert.AreEqual(GameState.Started, instance.GetGameStateAsObvserverX("GameName").State);
        }

        [Test]
        public void GetGameState_AfterPacManWasEatenAndThereAreOtherPacMenWaiting_GameStateShouldBeWatingForNextPacManToStart()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var pacMan1 = instance.JoinGameX("GameName", "PacMan1", PlayerRole.PacMan);
            var pacMan2 = instance.JoinGameX("GameName", "PacMan2", PlayerRole.PacMan);
            var ghost1 = instance.JoinGameX("GameName", "Ghost1", PlayerRole.Ghost);
            instance.UpdateMyWhereabouts(new ServerPollParameters(pacMan1.PlayerId, 5, 5, true));
            instance.UpdateMyWhereabouts(new ServerPollParameters(ghost1.PlayerId, 5, 5, true));

            Assert.AreEqual(GameState.WatingForNextPacManToStart, instance.GetGameStateAsObvserverX("GameName").State);
        }

        [Test]
        public void GetGameState_AfterSecondPacManEnabledItself_GameStateShouldBeStarted()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var pacMan1 = instance.JoinGameX("GameName", "PacMan1", PlayerRole.PacMan);
            var pacMan2 = instance.JoinGameX("GameName", "PacMan2", PlayerRole.PacMan);
            var ghost1 = instance.JoinGameX("GameName", "Ghost1", PlayerRole.Ghost);
            instance.UpdateMyWhereabouts(new ServerPollParameters(pacMan1.PlayerId, 5, 5, true));
            instance.UpdateMyWhereabouts(new ServerPollParameters(ghost1.PlayerId, 5, 5, true));
            instance.UpdateMyWhereabouts(new ServerPollParameters(pacMan2.PlayerId, 15, 15, true));

            Assert.AreEqual(GameState.Started, instance.GetGameStateAsObvserverX("GameName").State);
        }

        [Test]
        public void GetGameState_AfterLastPacManWasEaten_GameStateShouldBeGameOver()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var pacMan1 = instance.JoinGameX("GameName", "PacMan1", PlayerRole.PacMan);
            var ghost1 = instance.JoinGameX("GameName", "Ghost1", PlayerRole.Ghost);
            instance.UpdateMyWhereabouts(new ServerPollParameters(pacMan1.PlayerId, 5, 5, true));
            instance.UpdateMyWhereabouts(new ServerPollParameters(ghost1.PlayerId, 5, 5, true));

            Assert.AreEqual(GameState.GameOver, instance.GetGameStateForX(pacMan1.PlayerId).State);
        }


        [Test]
        public void GetGameState_AfterPacManAteLastApple_GameStateShouldBeGameOver()
        {
            var singleAppleLocation = new InitialApple { Lat = 2, Lon = 2 };
            var instance = ServerFacadeFactory.CreateGameWithApplesOnlyAt(singleAppleLocation);

            instance.CreateGameX("GameName");
            var pacMan1 = instance.JoinGameX("GameName", "PacMan1", PlayerRole.PacMan);
            instance.UpdateMyWhereabouts(new ServerPollParameters(pacMan1.PlayerId, singleAppleLocation.Lat, singleAppleLocation.Lon, true));

            Assert.AreEqual(GameState.GameOver, instance.GetGameStateForX(pacMan1.PlayerId).State);
        }

        [Test]
        public void GetGameState_AfterPacManAteNormalApple_GameStateShouldBeStarted()
        {
            var singleAppleLocation = new InitialApple { Lat = 2, Lon = 2 };
            var instance = ServerFacadeFactory.CreateGameWithExtraApplesAt(singleAppleLocation);

            instance.CreateGameX("GameName");
            var pacMan1 = instance.JoinGameX("GameName", "PacMan1", PlayerRole.PacMan);
            instance.UpdateMyWhereabouts(new ServerPollParameters(pacMan1.PlayerId, singleAppleLocation.Lat, singleAppleLocation.Lon, true));

            Assert.AreEqual(GameState.Started, instance.GetGameStateAsObvserverX("GameName").State);
        }

        [Test]
        public void GetGameState_AfterPacManAteSuperApple_GameStateShouldBeSuperPacMan()
        {
            var singleAppleLocation = new InitialApple { Lat = 2, Lon = 2, Type = AppleKind.Super };
            var instance = ServerFacadeFactory.CreateGameWithExtraApplesAt(singleAppleLocation);

            instance.CreateGameX("GameName");
            var pacMan1 = instance.JoinGameX("GameName", "PacMan1", PlayerRole.PacMan);
            instance.UpdateMyWhereabouts(new ServerPollParameters(pacMan1.PlayerId, singleAppleLocation.Lat, singleAppleLocation.Lon, true));

            Assert.AreEqual(GameState.SuperPacMan, instance.GetGameStateAsObvserverX("GameName").State);
        }
    }
}